#include <ncurses.h>

int LCD_ROW=MAX_MESG;

int pri2color[8];

#define fields 7
int field[fields]=
{
     3,
     3,
     15,
     3,
     3,
     5,
     MSG_LEN
};
char pri2text[][4]=
{
     "EMR",
     "ALR",
     "CRI",
     "ERR",
     "WRN",
     "NTC",
     "INF",
     "DEB"
};

int COLS_OLD,LINES_OLD;

#define __border( line, sign_1, sign_2, sign_3, sign_4 ) \
   mvaddch(line, 0, sign_1); \
   for (i=0;i<fields-1;i++) { \
      for (j=0;j<field[i];j++) \
	addch(sign_2); \
      addch(sign_3); \
   } \
   for (j=0;j<field[fields-1];j++) \
     addch(sign_2); \
   addch(sign_4)

#define LCD_print_xy(col,row,text,len) \
   mvaddstr(row,col,text)

int LCD_clr_line(int line)
{
   int i,j;
   if (mini)
       mvaddstr(line,0,"                                        ");
   else {
     __border(line+3,ACS_VLINE,' ',ACS_VLINE,ACS_VLINE);
   }
   return(0);
}

int LCD_rst()
{
   int i,j;
   if ( mini == 0 ) {
      __border(0,ACS_ULCORNER,ACS_HLINE,ACS_TTEE,ACS_URCORNER);
      mvaddch(1,0,ACS_VLINE);
      addstr("msg");
      addch(ACS_VLINE);
      addstr("cli");
      addch(ACS_VLINE);
      addstr("   IP address  ");
      addch(ACS_VLINE);
      addstr("nr ");
      addch(ACS_VLINE);
      addstr("pri");
      addch(ACS_VLINE);
      addstr("time ");
      addch(ACS_VLINE);
      addstr("              text                      ");
      addch(ACS_VLINE);
      __border(2,ACS_LTEE,ACS_HLINE,ACS_PLUS,ACS_RTEE);
   }
   for (i=0;i<LCD_ROW;i++)
     LCD_clr_line(i);
   if ( mini == 0 ) {
      __border(LCD_ROW+3,ACS_LLCORNER,ACS_HLINE,ACS_BTEE,ACS_LRCORNER);
   }
   return(0);

}

int LCD_init()
{
   initscr();
   keypad(stdscr, TRUE);
   nonl();
   cbreak();
   curs_set(0);
   COLS_OLD = COLS;
   LINES_OLD = LINES;
   mini = ( (COLS) < (80) ? (1) : (0) );
   if ( mini ) {
      LCD_ROW = LINES < MAX_MESG ? LINES : MAX_MESG;
   }
   else {
      LCD_ROW = ( LINES - 4 ) < MAX_MESG ?
	( LINES -4 ) : MAX_MESG;
   }
   if (has_colors()) {
      start_color();
      init_pair(1, COLOR_GREEN, COLOR_BLACK);
      init_pair(2, COLOR_WHITE, COLOR_BLACK);
      init_pair(3, COLOR_YELLOW, COLOR_BLACK);
      init_pair(4, COLOR_RED, COLOR_BLACK);
      init_pair(5, COLOR_WHITE, COLOR_RED);
      pri2color[0]=COLOR_PAIR(5) | A_BOLD | A_BLINK;	// MSG_EMERG	system is unusable
      pri2color[1]=COLOR_PAIR(5) | A_BOLD | A_BLINK;	// MSG_ALERT	action must be taken immediately
      pri2color[2]=COLOR_PAIR(5) | A_BOLD;		// MSG_CRIT	critical conditions
      pri2color[3]=COLOR_PAIR(4) | A_BOLD;		// MSG_ERR	error conditions
      pri2color[4]=COLOR_PAIR(3) | A_BOLD;		// MSG_WARNING	warning conditions
      pri2color[5]=COLOR_PAIR(2) | A_BOLD;		// MSG_NOTICE	normal but significant condition
      pri2color[6]=COLOR_PAIR(1) | A_BOLD;		// MSG_INFO	informational
      pri2color[7]=COLOR_PAIR(1) | A_BOLD;		// MSG_DEBUG	debug-level messages
      
      attrset(pri2color[7]);
   }
   LCD_rst();
   return(0);
}

int dsp_message(int msg_nr, int row)
{
   struct tm *time_rec;
   time_t tmp_time;
   int j;
//   char *c;
   
#define __disp(format,var) \
   printw(format,var); \
   addch(ACS_VLINE)
   
   if (mini)
     move(row,0);
   else {
      mvaddch(row+3,0,ACS_VLINE);
      __disp("%3d",msg_nr);
      __disp("%3d",message[msg_nr].client);
      printw("%.3d.%.3d.%.3d.%.3d",(message[msg_nr].addr.s_addr & 255),
	     (message[msg_nr].addr.s_addr >> 8 ) & 255,
	     (message[msg_nr].addr.s_addr >> 16 ) & 255,
	     (message[msg_nr].addr.s_addr >> 24 ) & 255);
      addch(ACS_VLINE);
      tmp_time=(time_t) message[msg_nr].time;
      time_rec=localtime(&tmp_time);
      __disp("%3d",message[msg_nr].nr);
      addstr(pri2text[(int) (message[msg_nr].pri) ]);
      addch(ACS_VLINE);
      printw("%.2d:%.2d",
	     (*time_rec).tm_hour,(*time_rec).tm_min);
      addch(ACS_VLINE);
   }

   if (has_colors())
     attrset(pri2color[(int) (message[msg_nr].pri)]);
   for (j=0;j<MSG_LEN;j++) {
      if ( message[msg_nr].mesg[j] == 0 ) {
//	 attron(A_REVERSE);
	 addch(0xA4);
//	 attroff(A_REVERSE);
      }
      else if ( message[msg_nr].mesg[j] < 8 ) {
	 attron(A_REVERSE);
	 addch(message[msg_nr].mesg[j]+'0');
	 attroff(A_REVERSE);
      }
      else if ( message[msg_nr].mesg[j] == 0xFF ) {
	 attron(A_REVERSE);
	 addch('8');
	 attroff(A_REVERSE);
      }
      else
	addch(message[msg_nr].mesg[j]);
   }
   if (has_colors())
     attrset(pri2color[7]);
   return(0);
}

void LCD_close()
{
   clear();
   nl();
   refresh();
   endwin();
}

int term_resize()
{
   int i;
   if ( ( COLS_OLD != COLS ) ||
	( LINES_OLD != LINES ) ) {
      for ( i=0; i<MAX_MESG; i++ ) {
	 on_display[0][i]=on_display[1][i]=-1;
      }
      LCD_close();
      return(LCD_init());
   }
   else
     return(0);
}
